<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>滚筒式洗衣机</title>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.9.1/gsap.min.js"></script>
  <script src="https://libs.baidu.com/jquery/2.1.4/jquery.min.js"></script>
  <style>
    @charset "UTF-8";
    @import url("https://fonts.googleapis.com/css?family=Nova+Mono&display=swap");

    * {
      box-sizing: border-box;
      padding: 0;
      margin: 0
    }

    body {
      display: flex;
      height: 100vh;
      background: #92bfd1;
      font-size: 14px;
      font-family: 'Nova Mono', monospace
    }

    #wrapper {
      margin: auto;
      display: flex;
      flex-direction: column;
      align-items: center
    }

    #washingMachine {
      background: #ececf4;
      width: 300px;
      height: 388.2352941176px;
      border-radius: 15px;
      border-top: 15px solid #80819c;
      display: flex;
      align-items: center;
      justify-content: center;
      position: relative;
      overflow: hidden;
      box-shadow: inset -15px -15px 0 0 rgba(196, 196, 210, 0.3);
      padding: 85px 0 45px
    }

    #washingMachine:before, #washingMachine:after {
      content: "";
      position: absolute;
      border: 4px solid transparent;
      width: 150%
    }

    #washingMachine:before {
      border-bottom-color: #c4c4d2;
      height: 70px;
      top: 0;
      border-radius: 50%;
      box-shadow: inset 0 -15px 0 0 rgba(196, 196, 210, 0.3)
    }

    #washingMachine:after {
      border-top-color: #c4c4d2;
      height: 30px;
      bottom: 0
    }

    #washingMachine #controls {
      top: 19.0909090909px;
      text-align: center;
      right: 30px;
      background: #242527;
      color: lightgreen;
      border-radius: 5px;
      padding: 3px 10px;
      font-weight: 500;
      font-size: 1em;
      justify-content: center
    }

    #washingMachine #controls, #washingMachine #controls:before, #washingMachine #controls:after {
      position: absolute
    }

    #washingMachine #controls, #washingMachine #controls:after {
      height: 23.8636363636px;
      min-width: 60px
    }

    #washingMachine #controls, #washingMachine #controls:before {
      display: flex;
      align-items: center;
      transition: all 0.2s cubic-bezier(0.56, 0.35, 0, 1.35)
    }

    #washingMachine #controls:before {
      content: "━━";
      font-size: 14px;
      color: #80819c;
      box-shadow: inset 0px -15px 0px 0px rgba(196, 196, 210, 0.3);
      height: 31.8181818182px;
      width: 31.8181818182px;
      border: 3px solid #c4c4d2;
      border-radius: 100%;
      transform: rotate(0deg);
      left: calc(100% + -135.9090909091px)
    }

    #washingMachine #controls:after {
      content: "";
      left: calc(100% + -240px);
      background: rgba(196, 196, 210, 0.3);
      border-radius: 3px 3px 10px 10px;
      border: 3px solid #c4c4d2;
      box-shadow: inset 0 10px 0 0 #c4c4d2
    }

    #washingMachine #door, #washingMachine #tub {
      transition: all 0.2s ease-in-out
    }

    #washingMachine #door {
      width: 200px;
      height: 200px;
      border: 25px solid #80819c;
      border-radius: 50%;
      position: absolute;
      z-index: 1;
      box-shadow: inset 5px 10px 0 0 rgba(0, 0, 0, 0.1), 5px -1px 0 0 transparent;
      transform-origin: 0% 0%;
      transform: rotateY(0deg)
    }

    #washingMachine #door:before, #washingMachine #door:after {
      content: "";
      position: absolute;
      top: 50%;
      transform: translateY(-50%)
    }

    #washingMachine #door:after {
      background: #666783;
      height: 50%;
      width: 17%;
      right: 0;
      border-radius: 40% 30% 30% 40% / 50% 45% 45% 50%;
      transition: all 0.2s ease-in-out;
      z-index: 3
    }

    #washingMachine #door:before {
      width: 60%;
      height: 60%;
      left: 0;
      right: 0;
      margin: auto;
      border-radius: 50%;
      border: 5px solid transparent;
      border-left: 15px solid white;
      transform: translateY(-50%) rotate(45deg);
      opacity: 0.2;
      box-shadow: inset -10px 10px 0 0 rgba(255, 255, 255, 0.2);
      border-radius: 40% 30% 30% 40% / 50%;
      z-index: 2
    }

    #washingMachine #tub {
      width: 175px;
      height: 175px;
      background: #453e57;
      position: relative;
      border-radius: 50%;
      overflow: hidden;
      z-index: 0;
      box-shadow: 0 0 0 7px rgba(196, 196, 210, 0.3)
    }

    #washingMachine #tub .clothes {
      position: absolute;
      opacity: 0;
      transition: all 0.1s ease-in-out
    }

    #washingMachine #tub .clothes:nth-child(1) {
      background: linear-gradient(#48873e, #7b9f17);
      width: 70%;
      height: 25%;
      bottom: 10%;
      right: -20%;
      transform: rotate(-20deg);
      border-radius: 49% 38% 65% 8% / 30% 12% 51% 36%
    }

    #washingMachine #tub .clothes:nth-child(2) {
      background: linear-gradient(#c22323, #e15050);
      width: 100%;
      height: 20%;
      border-radius: 64% 40% 27% 47% / 63% 63% 32% 36%;
      bottom: 0
    }

    #washingMachine #tub .clothes:nth-child(3) {
      background: linear-gradient(#5a5589, #4f46b4);
      width: 70%;
      height: 25%;
      transform: rotate(40deg);
      border-radius: 41% 38% 71% 8% / 51% 36% 51% 24%;
      bottom: 0;
      left: -10%
    }

    #washingMachine.isOpen #door {
      transform: rotateY(45deg);
      box-shadow: inset 5px 10px 0 0 transparent, 5px -1px 0 0 #b9bac9
    }

    #washingMachine.isOpen #door:after {
      box-shadow: 5px -1px 0 0 #505166
    }

    #washingMachine.isOpen #tub {
      box-shadow: inset 5px 10px 0 0 rgba(0, 0, 0, 0.1), 0 0 0 7px rgba(196, 196, 210, 0.3)
    }

    #washingMachine.isWashing {
      animation-name: shake;
      animation-duration: 100ms;
      animation-timing-function: ease-in-out;
      animation-iteration-count: infinite
    }

    #washingMachine.isWashing #controls:before {
      transform: rotate(45deg)
    }

    #washingMachine.isWashing #tub {
      animation-name: rotate;
      animation-duration: 0.6s;
      animation-timing-function: linear;
      animation-iteration-count: infinite
    }

    #washingMachine.isFilled #tub .clothes {
      opacity: 1
    }

    #washingMachine.isStarting {
      animation-duration: 200ms;
      animation-timing-function: cubic-bezier(0, -0.01, 0.61, 0.01)
    }

    #washingMachine.isStarting #tub {
      animation-duration: 1.2s;
      animation-timing-function: cubic-bezier(0, -0.01, 0.61, 0.01)
    }

    @keyframes shake {
      0%, 100% {
        transform: translate(0, 0) rotate(0)
      }
      25% {
        transform: translate(-1.5px, 1.5px) rotate(0.5deg)
      }
      50% {
        transform: translate(-0.5px, -0.5px) rotate(0.5deg)
      }
    }

    @keyframes rotate {
      from {
        transform: rotate(0deg)
      }
      to {
        transform: rotate(360deg)
      }
    }

    #playground {
      margin-top: 25px;
      width: 300px;
      display: flex
    }

    #playground button {
      flex: 1;
      background: #ececf4;
      border: none;
      outline: none;
      border-radius: 6px;
      padding: 7px 10px;
      box-shadow: -1px 2px 0 0 rgba(0, 0, 0, 0.2);
      transition: background 0.2s ease-in-out;
      font: inherit;
      font-size: 0.8em
    }

    #playground button#opening {
      margin: 0 15px
    }

    #playground button:hover:not(:disabled) {
      background: white;
      cursor: pointer
    }

    #playground button::-moz-focus-inner {
      border: 0
    }

    #playground button:active:not(:disabled) {
      box-shadow: 0px 1px 0 0 rgba(0, 0, 0, 0.2)
    }
  </style>
</head>

<body>
<div id="wrapper">
  <div id="washingMachine" class="isFilled isOpen">
    <div id="controls">准备中</div>
    <div id="door"></div>
    <div id="tub">
      <span class="clothes"></span>
      <span class="clothes"></span>
      <span class="clothes"></span>
    </div>
  </div>

  <div id="playground">
    <button id="content">清空</button>
    <button id="opening">关门</button>
    <button id="power" disabled>开始</button>
  </div>
</div>
</body>
<script>
  const washSpeed = 600;
  const washingMachine = document.getElementById('washingMachine');
  const screen = document.getElementById('controls');
  const status = {
    opening: {
      isActive: true,
      statusClass: 'isOpen',
      controller: document.getElementById('opening'),
      controllerLabel: ["关门", "开门"]
    },
    content: {
      isActive: true,
      statusClass: 'isFilled',
      controller: document.getElementById('content'),
      controllerLabel: ["清空", "加满"]
    },
    power: {
      isActive: false,
      statusClass: 'isWashing',
      controller: document.getElementById('power'),
      controllerLabel: ["停止", "开始"]
    }
  };
  for (let action in status) {
    const {statusClass, controller, controllerLabel} = status[action];
    controller.addEventListener('click', function (event) {
      const {isActive} = status[action];
      washingMachine.classList.toggle(statusClass);
      this.innerHTML = controllerLabel[isActive * 1];
      if (action === "power" && !isActive) {
        washingMachine.classList.add(statusClass);
        washingMachine.classList.add("isStarting");
        setTimeout(() => {
          washingMachine.classList.remove("isStarting")
        }, washSpeed * 2)
      }
      status[action].isActive = !isActive;
      setTimeout(function () {
        updateMachine()
      }, 100)
    })
  }

  function updateMachine() {
    const {opening, content, power} = status;
    opening.controller.disabled = power.isActive;
    content.controller.disabled = !opening.isActive;
    power.controller.disabled = opening.isActive || !content.isActive;
    if (power.isActive) {
      screen.innerHTML = "清洗"
    } else if (!content.isActive) {
      screen.innerHTML = "准备中"
    } else if (opening.isActive) {
      screen.innerHTML = "清洗"
    } else {
      screen.innerHTML = "准备中"
    }
  }
</script>

</html>